<?php

namespace Sbm;

/**
 * Описание объекта Заказ
 * 
 */
class Order
{

	/**
	 * Номер заказа в базе данных
	 * @var <int> id
	 */
	var $id;

	/**
	 * Время последнего изменения заказа
	 * @var <int> time
	 */
	var $time;
	/*
	 * Статус заказа. 
	 * Может принимать значения 'open','closed','in_process' 
	 * @var <string> status
	 */

	private $status;

	/**
	 * Описание статуса. Например, если заказ закрыт, то описание причины закрытия
	 * @var <string> status_description
	 */
	var $status_description;

	/**
	 * Является ли заказ историей.
	 * @var <boolean> history
	 */
	var $history;


	//{{{

	/**
	 * Описание заказа
	 * @var string Description
	 */
	var $defect;

	/**
	 * Оборудование, которое сломалось
	 * @var Equipment Description
	 */
	var $equipment;

	/**
	 * Профессия, необходимая для выполения заказа
	 * @var Profession Profession
	 */
	var $profession;

	//}}}
	//{{{ 

	/**
	 * Удобное для пользователя время работ
	 * @var <int>
	 */
	var $customer_time;

	/**
	 * Телефон заказчика
	 * @var <string> phone
	 */
	var $phone;

	/**
	 * Имя заказчика
	 * @var <string> customer_name
	 */
	var $customer_name;

	/**
	 * Адрес заказчика
	 * @var <string> address
	 */
	var $address;

	/**
	 * Регион, в котором нужно сделать заказ
	 * @var Region Region
	 */
	var $region;

	//}}}
	//{{{

	/**
	 * Мастер, который взял заказа
	 * @var Master master
	 */
	var $master;

	//}}}

	/**
	 * Цена заказа
	 */
	var $price;

	/**
	 * 
	 * @param array $init_array
	 * @return Order
	 */
	function __construct( $init_array = NULL )
	{
		$this->Init($init_array);
	}

	function Init( $array = NULL )
	{
		if ( !$array )
		{
			$this->region = new Region();
			$this->profession = new Profession();
			$this->equipment = new Equipment();
			$this->master = new Master();
		}
		else
		{
			$this->id = empty($array['id']) ? NULL : $array['id'];
			$this->time = empty($array['time']) ? time() : strtotime($array['time']);
			$this->status = empty($array['status']) ? '' : $array['status'];
			$this->status_description = empty($array['status_description']) ? '' : $array['status_description'];
			$this->defect = empty($array['defect']) ? '' : $array['defect'];
			;
			$this->customer_time = empty($array['customer_time']) ? NULL : strtotime($array['customer_time']);
			$this->customer_name = empty($array['customer_name']) ? '' : $array['customer_name'];
			$this->address = empty($array['address']) ? '' : $array['address'];
			$this->phone = empty($array['phone']) ? '' : $array['phone'];

			$this->region = new Region();
			$this->region->id = empty($array['region_id']) ? NULL : $array['region_id'];
			$this->region->title = empty($array['region_title']) ? '' : $array['region_title'];

			$this->profession = new Profession();
			$this->profession->id = empty($array['profession_id']) ? NULL : $array['profession_id'];
			$this->profession->title = empty($array['profession_title']) ? '' : $array['profession_title'];

			$this->equipment = new Equipment();
			$this->equipment->id = empty($array['equipment_id']) ? NULL : $array['equipment_id'];
			$this->equipment->title = empty($array['equipment_title']) ? '' : $array['equipment_title'];

			$this->master = new Master();
		}
	}

	/**
	 * Возвращает объект Equipment 
	 * @return Equipment
	 */
	function GetEquipment()
	{
		return $this->equipment;
	}

	function GetEquipmentName()
	{
		return $this->equipment_name;
	}

	/**
	 * Устанавливает статус заказа
	 * 
	 * @param string $status
	 * @return string
	 */
	public function SetStatus( $status )
	{
		if ( in_array($status, array('edit', 'insert', 'pending', 'closed', 'work')) )
		{
			return $status;
		}
		else
		{
			trigger_error("Status not defined", E_USER_ERROR);
		}
	}

	/**
	  public function GetStatus()
	  {
	  return $this->status;
	  }

	  /**
	 * Возвращает русское описание статуса
	 * 
	 * @return string 
	 */
	public function GetStatusText()
	{
		switch ($this->status)
		{
			case 'insert':
				return 'добавлен';
				break;
			case 'edit':
			case 'edited':
				return 'отредактирован';
				break;
			case 'pending':
				return 'ожидает мастера';
				break;
			case 'work':
				return 'в работе';
			case 'closed':
				return 'закрыт';
			default:
				trigger_error("Incorrect status", E_USER_WARNING);
				break;
		}
	}

	function GetSummary()
	{
		$string = $this->GetEquipment()->GetName() . "; " . $this->defect . "<br/>"
				. $this->GetStatus();

		return $string;
	}

	/**
	 * Сохраняет историю о заказе
	 * 
	 * @param DB $db
	 * @param array $fields
	 * @return void
	 */
	private function SaveHistory( $db, $fields )
	{
		$keep_fields = sprintf("`%s`", implode("`,`", $fields));
		$s = "INSERT INTO 
		            	`{history}` 
		               	(" . $keep_fields . ") 
		                SELECT " . $keep_fields . " FROM `{order}` WHERE `id` ='" . $this->id . "'";
		$db->Query($s);
	}

	/**
	 * Добавляет новый заказа в таблицу `order`
	 * @param DB $db
	 * @param array $fields
	 * @return int
	 */
	private function Insert( &$db, $fields )
	{
		$s = "INSERT
		                `{order}`
		                (`" . implode("`,`", array_keys($fields)) . "`) 
		      VALUES
		                ('" . implode("','", array_values($fields)) . "')";
		$q = $db->Query($s);
		return $db->InsertedId();
	}

	/**
	 * Обновляет заказ в базе данных
	 * 
	 * @param DB $db
	 * @param array $fields
	 * @return void
	 */
	private function Update( $db, $fields )
	{

		function get_sql_fields( $key, $value )
		{
			return sprintf("`%s` = '%s'", $key, $value);
		}

		$this->SaveHistory($db, array_keys($fields));

		$sql_fields = implode(",", array_map('get_sql_fields', array_keys($fields), array_values($fields)));

		$s = "UPDATE
		                `{order}`
		      SET " . $sql_fields . "
		      WHERE
		                `id`='" . $fields['id'] . "'";
		$q = $db->Query($s);
	}

	/**
	 * Сохраняет объект используя DB
	 * 
	 * @param DB $db
	 * @return int
	 */
	function Save( &$db )
	{
		$new_time = time();

		//{{{ Prepare fields

		$fields = array(
			'id' => $this->id,
			'time' => strftime("%Y-%m-%d %H:%M:%S", $new_time),
			'status' => $db->Escape($this->status),
			'status_description' => $db->Escape($this->status_description),
			'defect' => $db->Escape($this->defect),
			'equipment_id' => $this->equipment->id,
			'profession_id' => $this->profession->id,
			'customer_time' => strftime("%Y-%m-%d %H:%M:%S", $this->customer_time),
			'phone' => $db->Escape($this->phone),
			'customer_name' => $db->Escape($this->customer_name),
			'address' => $db->Escape($this->address),
			'region_id' => $db->Escape($this->region->id),
			'master_id' => $this->master->id,
		);

		//}}}
		//{{{ Сохраняем "историю заказа" 
		if ( $this->id )
		{
			$this->Update($db, $fields);
		}
		else
		{
			$this->id = $this->Insert($db, $fields);
		}
		//}}}

		$this->time = $new_time;

		return $this->id;
	}

}